using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using gudusoft.gsqlparser;
using gudusoft.gsqlparser.Units;


namespace prettyprint
{
    class prettyprint
    {
        static void Main(string[] args)
        {
            string usage = "Demo of General SQL Parser at http://www.sqlparser.com" + Environment.NewLine
            + "Usage:" + Environment.NewLine
             + "prettyprint -i insql.txt  -d mssql -t sql -o outsql.txt" + Environment.NewLine
             + "-i insql.txt, \t input sql file, must be specified" + Environment.NewLine
            + "-d mssql, \t sql engine used to handle the input sql, can be one of: access, db2,mssql,mysql,oracle, if ommitted, mssql engine will be used as default" + Environment.NewLine
            + "-o outsql.txt, \t save the output to this file,if ommitted, will write to stand output";


            if (args.Length == 0)
            {
                Console.WriteLine(usage);
                return;
            }

            string inputfile = "";
            string dbvendor = "";
            string outfile = "";

            for (int t = 0; t < args.Length; t++)
            {
                if (args[t] == "-i")
                {
                    if (t + 1 < args.Length)
                    {
                        inputfile = args[t + 1];
                    }
                }

                if (args[t] == "-d")
                {
                    if (t + 1 < args.Length)
                    {
                        dbvendor = args[t + 1];
                    }
                }


                if (args[t] == "-o")
                {
                    if (t + 1 < args.Length)
                    {
                        outfile = args[t + 1];
                    }
                }
            }


            Console.WriteLine("Input sql file: " + inputfile);
            Console.WriteLine("db engine used: " + dbvendor);
            Console.WriteLine("output file: " + outfile);

            string lcsqltext = "";

            //Reading from file
            try
            {
                StreamReader re = File.OpenText(inputfile); //new StreamReader(inputfile,new UnicodeEncoding());//
                // Console.WriteLine("The encoding used was {0}.", re.CurrentEncoding);

                string input = null;
                while ((input = re.ReadLine()) != null)
                {
                    lcsqltext = lcsqltext + input + Environment.NewLine;
                    // Console.WriteLine(input);
                }
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }


            //Create instance of sql parser according to database vendor you selected
            TDbVendor dbv;
            if (dbvendor == "access")
            {
                dbv = TDbVendor.DbVAccess;
            }
            else if (dbvendor == "db2")
            {
                dbv = TDbVendor.DbVDB2;
            }
            else if (dbvendor == "mssql")
            {
                dbv = TDbVendor.DbVMssql;
            }
            else if (dbvendor == "mysql")
            {
                dbv = TDbVendor.DbVMysql;
            }
            else if (dbvendor == "oracle")
            {
                dbv = TDbVendor.DbVOracle;
            }
            else
            {
                dbv = TDbVendor.DbVMssql;
            }

            TGSqlParser sqlparser = new TGSqlParser(dbv);
            Console.WriteLine(lzbasetype.DbVendorStr[(int)dbv]);


            //set the input sql text	
            sqlparser.SqlText.Text = lcsqltext;
            Console.WriteLine(sqlparser.SqlText.Text);

            //set the format options, lzbasetype.gFmtOpt is a global variable used to set formatter parameters
            // Format Options:
            //   TCaseOption = (coUppercase,coLowercase,coInitCap,coNoChange);  
            //   TLinefeedsCommaOption = (lfAfterComma,lfBeforeComma,lfbeforeCommaWithSpace,lfNolinebreakComma);
            //   TLinefeedsAndOrOption = (lfbeforeAndOr,lfAfterAndOr,lfNolinebreak);
            //   TAssignmentOption = (aoCompact,aoFixed);
            //   TAlignOption = (aloLeft,aloRight);
            //   TAlignStyle = (asStacked,asWrapped);
            //   TAlignStyleStacked = (assCompact,assFixed);


            lzbasetype.gFmtOpt.Select_keywords_alignOption = TAlignOption.aloLeft;//aloRight;
            lzbasetype.gFmtOpt.case_keywords = TCaseOption.coUppercase;
            lzbasetype.gFmtOpt.case_funcname = TCaseOption.coInitCap;
            lzbasetype.gFmtOpt.case_datatype = TCaseOption.coUppercase;
            lzbasetype.gFmtOpt.case_quoted_identifier = TCaseOption.coNoChange;
            lzbasetype.gFmtOpt.Select_Columnlist_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Insert_keywords_alignOption = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Insert_Columnlist_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Insert_Valuelist_Style = TAlignStyle.asWrapped;
            lzbasetype.gFmtOpt.Select_fromclause_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Select_Orderby_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Select_Groupby_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.LinefeedsComma_option = TLinefeedsCommaOption.lfAfterComma;
            lzbasetype.gFmtOpt.LinefeedsAndOr_option = TLinefeedsAndOrOption.lfbeforeAndOr;
            lzbasetype.gFmtOpt.Delete_keywords_alignOption = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Update_keywords_alignOption = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Update_Columnlist_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Expression_Align_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.VarAlign_option = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Parameters_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Parameters_align_option = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Parameters_Comma = TLinefeedsCommaOption.lfAfterComma;
            lzbasetype.gFmtOpt.Createtable_Fieldlist_Style = TAlignStyle.asStacked;
            lzbasetype.gFmtOpt.Createtable_Fieldlist_Align_option = TAlignOption.aloLeft;
            lzbasetype.gFmtOpt.Createtable_Fieldlist_Comma_option = TLinefeedsCommaOption.lfAfterComma;
            lzbasetype.gFmtOpt.AndOrUnderWhere = false;
            lzbasetype.gFmtOpt.AlignAliasInSelectList = true;
            lzbasetype.gFmtOpt.SelectItemInNewLine = true;
            lzbasetype.gFmtOpt.IndentLen = 2;
            lzbasetype.gFmtOpt.CaseWhenThenInSameLine = false;

           // lzbasetype.gFmtOpt.CompactMode = TCompactMode.cpmugly;
           // lzbasetype.gFmtOpt.LineWidth = 4000;


            lzbasetype.gFmtOpt.EmptyLines = TEmptyLinesOption.eloMergeIntoOne; //eloRemove;//eloPreserve;//eloMergeIntoOne;
            // lzbasetype.gFmtOpt.SelectItemInNewLine = false;//true;
            // lzbasetype.gFmtOpt.FromClauseInNewLine = false;//true;
            //  lzbasetype.gFmtOpt.CompactMode = TCompactMode.cpmugly;
            //  lzbasetype.gFmtOpt.MaxLengthPerLine = 80;

            // use tab to ident instead of space
            // lzbasetype.gFmtOpt.UseTab = true;
            // lzbasetype.gFmtOpt.TabSize = 4;

            // align if,begin,else, end if keywords in a sql block
            // lzbasetype.gFmtOpt.AlignIFStatement = true;

            lzbasetype.gFmtOpt.case_identifier = TCaseOption.coNoChange;
            // lzbasetype.gFmtOpt.case_identifier =  TCaseOption.coInitCapEachWord;
            // dictionaryfile must be set if case_identifier is set to TCaseOption.coInitCapEachWord
            // lzbasetype.gFmtOpt.DictionaryFile = "english.dic";

            string outputstr = "";

            Console.WriteLine("Working...");
            // Console.WriteLine(lcsqltext);


            int i = sqlparser.PrettyPrint();


            if (i == 0)
            {
                outputstr = sqlparser.FormattedSqlText.Text;

            }
            else
                Console.WriteLine(sqlparser.ErrorMessages);

            if (outfile.Length > 0)
            {
                //save to file
                StreamWriter w = File.CreateText(outfile);
                w.Write(outputstr);
                w.Flush();
                w.Close();
                Console.WriteLine(outfile + " was created");

            }
            else
            {
                Console.WriteLine(outputstr);
            }

        }
    }
}
